package com.ruoyi.framework.config;

import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.ruoyi.common.utils.TenantUtils;
import com.ruoyi.framework.config.properties.TenantProperties;
import com.ruoyi.framework.web.service.TokenService;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.StringValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.List;
import java.util.Set;

/**
 * 这个类实现了 MyBatis Plus 的 TenantLineHandler 接口，负责两件事：
 * 告诉拦截器当前操作的租户ID是什么。
 * 告诉拦截器当前操作的表是否应该被忽略。
 */
@Component
public class MyTenantLineHandler implements TenantLineHandler {

    private static final Logger log = LoggerFactory.getLogger(MyTenantLineHandler.class);

    @Autowired
    private TenantProperties tenantProperties;
    @Autowired
    private TokenService tokenService;

    /**
     * 【核心修改】
     * 只有当用户选择了租户时，才返回真实的租户ID。
     * 否则，我们返回一个特殊的、无效的ID（如0L），并配合 shouldFilter 方法来确保拦截器不工作。
     */
    @Override
    public Expression getTenantId() {
//        Long currentTenantId = /*TenantUtils.getCurrentTenantId()*/0L;
        String currentTenantId = TenantUtils.get();
        ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        List<Object> shopIds = tokenService.getUserShopId(servletRequestAttributes.getRequest());
        if (currentTenantId == null) {
            // 当没有租户ID时，返回一个不可能匹配任何记录的ID
            // 真实的过滤逻辑由 shouldFilter 控制
            return new NullValue();
        }
        
        return new StringValue(currentTenantId);
    }

    /**
     * 获取租户ID的数据库字段名
     */
    @Override
    public String getTenantIdColumn() {
        return tenantProperties.getColumn(); // 从配置文件获取
    }

    /**
     * 这是一个总开关。只有当用户登录并明确选择了某个租户后，才允许拦截器进行SQL处理。
     * 否则，拦截器应忽略所有表。
     *
     * @param tableName 表名
     * @return 是否忽略。true = 忽略，false = 不忽略（进行处理）
     */
    @Override
    public boolean ignoreTable(String tableName) {
        // 如果用户还未选择租户，则忽略所有表
        String currentTenantId = TenantUtils.get();
        if (currentTenantId == null) {
            log.debug("No tenant selected, ignoring all tables.");
            return true;
        }

        // 如果用户已选择租户，则根据配置文件中的 ignore-tables 列表来判断
        Set<String> ignoreTables = tenantProperties.getIgnoreTables();
        boolean shouldIgnore = ignoreTables != null && ignoreTables.stream()
                .anyMatch(item -> item.equalsIgnoreCase(tableName.trim()));

        if (shouldIgnore) {
            log.debug("Table [{}] is in ignore-tables list, skipping.", tableName);
        } else {
            log.debug("Table [{}] is not in ignore-tables list, applying tenant filter.", tableName);
        }

        return shouldIgnore;
    }
}
 